<?php
/**
* @package PankLink
* @author Jesper Saron, Oliver Leisalu
* @package BankLink
*/
final class NordeaLink extends BankLink {
	
	/**
	* Private key.
	* @var String
	*/
	protected $privateKey;
	/**
	* Reseller identification code
	* @var String
	*/
	protected $resellerId;
	/**
	* Account number
	* @var String
	*/
	protected $resellerAccount;
	/**
	* Account owner
	* @var String
	*/
	protected $resellerName;
	/**
	* Server to where request is sent.
	* @var String
	*/
	protected $serverUrl;
	/**
	* Url to where user is sent back from bank
	* @var String
	*/
	protected $callbackUrl;

	/**
	 * Function returns all the input fields required by the bank using BankPayment object.
	 *
	 * @param BankPayment $payment
	 * @return string HTML including input=hidden tags
	 */
	public function sendToBank( $callBackId, BankPayment $payment ) {
		
		if ( strpos($payment->price, ",") ) {
			$payment->price = (float)str_replace(",", ".", $payment->price);
		}
		
		$_SESSION['_PANKLINK_NORDEA_PRICE'] = $payment->price;
		
		$rsField = array(
			'SOLOPMT_VERSION'    => '0003',
            'SOLOPMT_STAMP'      => $callBackId,
            'SOLOPMT_RCV_ID'     => $this->resellerId,
			'SOLOPMT_RCV_ACCOUNT'        => $this->resellerAccount,
            'SOLOPMT_RCV_NAME'       => $this->resellerName,
			'SOLOPMT_LANGUAGE' 	 => "4",
			'SOLOPMT_AMOUNT'     => $payment->price,
			'SOLOPMT_REF'        => $this->referenceNumber($callBackId),
			'SOLOPMT_DATE'		 => 'EXPRESS',
            'SOLOPMT_CURR'       => $payment->currency,
            'SOLOPMT_MSG'        => $payment->description,
			'SOLOPMT_RETURN'     => $this->callbackUrl,
			'SOLOPMT_CANCEL'     => $this->callbackUrl,
			'SOLOPMT_REJECT'     => $this->callbackUrl,
			'SOLOPMT_CONFIRM'    => 'YES',
			'SOLOPMT_KEYVERS'	 => '0001',
			'SOLOPMT_CUR'		 => $payment->currency
       	);

       	$rsField['SOLOPMT_MAC'] = strtoupper(md5(
       		$rsField['SOLOPMT_VERSION'] . "&" .
       		$rsField['SOLOPMT_STAMP'] . "&" .
       		$rsField['SOLOPMT_RCV_ID'] . "&" .
       		$rsField['SOLOPMT_AMOUNT'] . "&" .
       		$rsField['SOLOPMT_REF'] . "&" .
       		$rsField['SOLOPMT_DATE'] . "&" .
       		$rsField['SOLOPMT_CUR'] . "&" .
       		$this->privateKey . "&"));

    	$html = '';
    	foreach ($rsField as $ixField => $fieldValue) {
    		$html .= '<input type="hidden" name="' . $ixField . '" value="' . htmlspecialchars(iconv($this->inputEncoding, $this->outputEncoding, $fieldValue)) . '" />' . "\n";
    	}
    	
    	echo self::getFormBase($this, $html);
		die();
	}
	/**
	 * Function that processes the callback from the bank and returns BankPayment objects with isSuccessful
	 * (and other applicable) parameters filled according to the answers from the bank.
	 *
	 * @return BankPayment
	 */
	protected function handleCallback() {
		$rsField = array();

	    foreach ((array)$_REQUEST as $ixField => $fieldValue) {
	        if (substr($ixField, 0, 8) == 'SOLOPMT_') {
	            $rsField[$ixField] = $fieldValue;
	        }
	    }
		
		$key = strtoupper(md5($rsField['SOLOPMT_RETURN_VERSION'] . "&" .$rsField['SOLOPMT_RETURN_STAMP'] . "&" .$rsField['SOLOPMT_RETURN_REF'] . "&" .$rsField['SOLOPMT_RETURN_PAID'] . "&" .$this->privateKey . "&"));
		
		// Invalid signature
		if ($key != $rsField['SOLOPMT_RETURN_MAC']) {
			return array('status' => 4, 'logId' => $rsField['SOLOPMT_RETURN_STAMP'], 'bankError'=>'', 'bankErrorStr'=>'');

		// successful payment 
		} else if ( isset($rsField['SOLOPMT_RETURN_PAID']) ) {
			return array('status' => 1, 'logId' => $rsField['SOLOPMT_RETURN_STAMP'], 'bankError'=>'', 'bankErrorStr'=>'');
		
	   // Payment was cancelled
	    } else {
			return array('status' => 3, 'logId' => $rsField['SOLOPMT_RETURN_STAMP'], 'bankError'=>'', 'bankErrorStr'=>'');
	    }
		return false;
	}

	/**
	* @internal
	*/
	protected function referenceNumber($ixOrder) {
		# reference number calculation using the algorithm provided by Pankade liit
		$rsMultiplier = array (7, 3, 1);
		$ixCurrentMultiplier = 0;
		$sixOrder = (string) $ixOrder;
		for ($i = strlen($sixOrder)-1; $i >= 0; $i--)
		{
			$rsProduct[$i] = substr($sixOrder, $i, 1)*$rsMultiplier[$ixCurrentMultiplier];
			if ($ixCurrentMultiplier == 2)
			{
				$ixCurrentMultiplier = 0;
			}
			else
			{
				$ixCurrentMultiplier++;
			}
		}
		$sumProduct = 0;
		foreach ($rsProduct as $product)
		{
			$sumProduct += $product;
		}
		if ($sumProduct % 10 == 0)
		{
			$ixReference = 0;
		}
		else
		{
			$ixReference = 10 - ($sumProduct % 10);
		}
		return $sixOrder.$ixReference;
	}
}
?>